
package org.sopt.dev.ImgKnight.frontier;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.DecimalFormat;

import org.apache.log4j.Logger;

import org.sopt.dev.ImgKnight.frontier.Config.FrontierConfig;
import org.sopt.dev.ImgKnight.frontier.Controller.AgentController;
import org.sopt.dev.ImgKnight.frontier.Controller.TelnetController;
import org.sopt.dev.ImgKnight.frontier.Queue.SiteMapHashTable;

public class Frontier {
	
	public static final int REQJOIN = 0xFDFDFDFD;
	
	public static final int REQDROP = 0xFEFEFEFE;
	
	public static final int SHUTDOWN = 0xFFFFFFFF;
	
	private FrontierConfig frontierConfig = null;
	
	private AgentController agentController = null;

	private TelnetController telnetController = null;
	
	private SiteMapHashTable siteMapHashTable = null;
	
	private Logger serviceLogger = null;
	
	public Frontier() {
		serviceLogger = Logger.getLogger("frontier.service");
	}
	
	public void init(boolean isCleanStart) throws FileNotFoundException, IOException {
		frontierConfig = new FrontierConfig();
		frontierConfig.BuildConfig(new File("frontier.properties"));
		
		siteMapHashTable = new SiteMapHashTable(frontierConfig.getSeedUrl(),
				frontierConfig.SiteMapCacheHighWaterMark,
				frontierConfig.SiteMapHashTableLowWaterMark,
				frontierConfig.SiteMapHashTableFetchSize, isCleanStart);
		
		agentController = new AgentController(siteMapHashTable);
		telnetController = new TelnetController((AgentController)agentController);
		serviceLogger.info("frontier init");
	}
	
	public void run() throws IllegalArgumentException {
		agentController.open();
		telnetController.open();
		serviceLogger.info("frontier start");
	}
	
	public synchronized void shutdown(int signal){
		siteMapHashTable.memToDisk();
		//agentController.BroadCastMessage(signal);
		try { Thread.sleep(2000); } catch (Exception ignored) {}
		agentController.close();
		telnetController.close();
		serviceLogger.info("frontier shutdown");
	}
	
	static Runtime runtime = Runtime.getRuntime();
	static DecimalFormat df = new DecimalFormat(",##0.00");
	public String getCondition() {
		return new String(
				(df.format((float)runtime.maxMemory()/1000000))+":"+
				(df.format((float)runtime.totalMemory()/1000000))+":"+
				(df.format((float)runtime.freeMemory()/1000000))+":"+
				siteMapHashTable.getHighPrioMemPushedCount()+":"+
				siteMapHashTable.getMemPushedCount()+":"+
				siteMapHashTable.getCachePushedCount()+":"+
				siteMapHashTable.getTovisitPushedCount()+":"+
				siteMapHashTable.getPopedCount()+":"+
				siteMapHashTable.getDuplicatedUrlCount()+":"+
				siteMapHashTable.getDiscardedUrlCount()+":"+
				siteMapHashTable.getHighPrioSiteHashMapSize()+":"+
				siteMapHashTable.getSiteHashMapSize()+":"+
				siteMapHashTable.getUrlDupFilterCurrentCount()+":"+
				siteMapHashTable.getUrlDupFilterFlushedCount());
	}
	
	public SiteMapHashTable getsiteMapHashTable() {
		return siteMapHashTable;
	}
	
	public AgentController getAgentController() {
		return agentController;
	}

	public TelnetController getTelnetController() {
		return telnetController;
	}
	
	public FrontierConfig getFrontierConfig() {
		return frontierConfig;
	}
	
	private static Frontier frontier = null;
	public static Frontier getInstance() {
		if( frontier == null )
			frontier = new Frontier();
		return frontier;
	}
	
}
